#include <head.h>

#define SIZE_BUF_MAX 1024

// 拷贝函数
void copy_file(int src_fd, int desk_fd, off_t start, off_t end)
{
    // 设定缓冲区
    char buf[SIZE_BUF_MAX];
    // 设定文件起始位置
    lseek(src_fd, start, SEEK_SET);
    lseek(desk_fd, start, SEEK_SET);

    // 开始拷贝
    size_t byte_read = 0;
    size_t byte_write = 0;

    while (start < end)
    {
        if ((byte_read = read(src_fd, buf, SIZE_BUF_MAX)) <= 0)
        {
            break;
        }
        if ((byte_write = write(desk_fd, buf, byte_read)) <= 0)
        {
            break;
        }

        // 位置迭代
        start += byte_write;
    }
}

int main(int argc, char const *argv[])
{
    // 安排判定
    if (3 != argc)
    {
        printf("格式错误 %s dest src\n", argv[0]);
        return 0;
    }

    // 打开文件
    int desk_fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0664); // 目标文件
    OPEN_ERR(desk_fd);

    int src_fd = open(argv[2], O_RDONLY  ); // 源文件
    OPEN_ERR(src_fd);

    // 获取文件状态
    struct stat file_stat; // 文件状态结构体

    if (fstat(src_fd, &file_stat) < 0)
    {
        perror("fstat err");
        close(desk_fd);
        close(src_fd);
        return 0;
    }

    // 获取文件大小 并计算每个进程 所拷贝的范围
    off_t file_size = file_stat.st_size; // 文件大小
    off_t part_size = file_size / 2;

    // 创建进程
    for (int i = 0; i < 2; i++)
    {
        pid_t pid = fork();

        if (0 > pid)
        {
            perror("fork error:");
            close(desk_fd);
            close(src_fd);
            exit(1);
        }
        else if (0 == pid)
        {
            off_t start = i * part_size; // 记录开始位置
            off_t end = (i == 1) ? file_size : part_size + start;
            // 拷贝文件
            copy_file(src_fd, desk_fd, start, end);
            // 关闭文件
            close(src_fd);
            close(desk_fd);

            exit(0);
        }
    }

    // 主进程 回收资源
    for (size_t i = 0; i < 2; i++)
    {
        wait(NULL);
    }

    // 关闭文件
    close(src_fd);
    close(desk_fd);

    return 0;
}